package com.thwj.project.app.event;

import cn.binarywang.wx.miniapp.api.WxMaService;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.thwj.common.exception.ServiceException;
import com.thwj.common.utils.StringUtils;
import com.thwj.common.utils.WzDateUtil;
import com.thwj.project.biz.domain.Activity;
import com.thwj.project.biz.domain.Merchant;
import com.thwj.project.biz.domain.MerchantProduct;
import com.thwj.project.biz.enums.ActivityChargeTypeEnum;
import com.thwj.project.biz.enums.MerchantStatusEnum;
import com.thwj.project.biz.enums.MessageTypeEnum;
import com.thwj.project.biz.service.*;
import com.thwj.project.pay.OrderNumberUtil;
import com.thwj.project.pay.WxPayManger;
import com.thwj.project.pay.dto.WxPayRefundDTO;
import com.thwj.project.pay.service.IWxPayService;
import com.thwj.project.push.enums.PushTemplateEnumNew;
import com.thwj.project.push.event.WxMpAdminMessageEvent;
import com.thwj.project.push.event.WxMpMessageEvent;
import com.thwj.project.system.service.ISysOssService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;

@Slf4j
@Component
public class ActivityEventConsumer {

    @Autowired
    IWxPayService wxPayService;
    @Autowired
    IUserAccountInoutService userAccountInoutService;
    @Autowired
    IUserAccountService userAccountService;
    @Autowired
    WxPayManger wxPayManger;
    @Autowired
    IMerchantService merchantService;
    @Autowired
    WxMaService wxMaService;
    @Autowired
    ISysOssService sysOssService;
    @Autowired
    IActivityService activityService;
    @Autowired
    ApplicationEventPublisher applicationEventPublisher;
    @Autowired
    IMerchantProductService merchantProductService;



    @Async
    @EventListener
    public void  onActivitySignUpSuccessEvent(ActivitySignUpSuccessEvent event) {
        //更新产品销量
        if(event.getActivity().getProductId() != null) {
            merchantProductService.update(new UpdateWrapper<MerchantProduct>()
                    .setSql("sale_count = sale_count + 1")
                    .eq("id", event.getActivity().getProductId()));
        }

        // 通知创建者
        applicationEventPublisher.publishEvent(WxMpMessageEvent.builder()
                .userId(event.getActivity().getUserId())
                .pushTemplateEnum(PushTemplateEnumNew.ACTIVITY_SIGN_UP_SUCCESS)
               // .miniAppPath("pages/detail/detail?activityId="+event.getActivity().getId())
                .templateDataList(PushTemplateEnumNew.ACTIVITY_SIGN_UP_SUCCESS(event.getActivity().getTitle() ,
                        event.getActivity().getLocationName(),
                        // 报名人联系方式
                        WzDateUtil.date2String(event.getActivity().getStartDate(),WzDateUtil.DATE_FORMAT_P) + "~" + WzDateUtil.date2String(event.getActivity().getEndDate(),WzDateUtil.DATE_FORMAT_P),
                         event.getSignup().getPhone())
                )
                .build()
        );

        // 通知报名人
        applicationEventPublisher.publishEvent(WxMpMessageEvent.builder()
                .userId(event.getSignup().getUserId())
                .pushTemplateEnum(PushTemplateEnumNew.ACTIVITY_SIGN_UP_SUCCESS)
               // .miniAppPath("pages/detail/detail?activityId="+event.getActivity().getId())
                .templateDataList(PushTemplateEnumNew.ACTIVITY_SIGN_UP_SUCCESS(event.getActivity().getTitle() ,
                        event.getActivity().getLocationName(),
                        // 报名人联系方式
                        WzDateUtil.date2String(event.getActivity().getStartDate(),WzDateUtil.DATE_FORMAT_P) + "~" + WzDateUtil.date2String(event.getActivity().getEndDate(),WzDateUtil.DATE_FORMAT_P),
                        event.getSignup().getPhone())
                )
                .build()
        );

        applicationEventPublisher.publishEvent(UserMessageEvent.builder()
                .userId(event.getSignup().getUserId())
                .type(MessageTypeEnum.ACTIVITY_MESSAGE)
                .withContent("活动报名成功", "成功报名：" + event.getActivity().getTitle())
                .withActivityParam(event.getActivity().getId())
                .build());

        applicationEventPublisher.publishEvent(UserMessageEvent.builder()
                .userId(event.getActivity().getUserId())
                .type(MessageTypeEnum.ACTIVITY_MESSAGE)
                .withContent("用户报名成功", "你发布的活动 "+ event.getSignup().getNickname() + " 报名成功")
                .withActivityParam(event.getActivity().getId())
                .build());
    }

    /***
     * 退款
     * @param event
     */
    @Async
    @TransactionalEventListener
    public void  onCancelActivitySignUpSuccessEvent(CancelActivitySignUpSuccessEvent event) {
        log.info("onCancelActivitySignUpSuccessEvent:取消报名 {}", event);
        // 判断是否发起退款
        if (ActivityChargeTypeEnum.AA_before.getValue() == event.getSignup().getChargeType() && event.getSignup().getActualMoney() != null && StringUtils.isNotEmpty(event.getSignup().getOrderNumber())) {
                // 发起退款
                WxPayRefundDTO wxPayRefundDTO = new WxPayRefundDTO();
                wxPayRefundDTO.setOutRefundNo(OrderNumberUtil.getOrderNumber());
                wxPayRefundDTO.setOutTradeNo(event.getSignup().getOrderNumber());
                wxPayRefundDTO.setTotalFee(event.getSignup().getActualMoney());
                wxPayRefundDTO.setRefundFee(event.getSignup().getActualMoney());
                try {
                    WxPayRefundResult payRefundResult = wxPayManger.wxMiniOrderRefund(wxPayRefundDTO);
                    log.info("用户取消预约活动发起退款：payRefundResult:{}",payRefundResult);
                }catch (WxPayException e){
                    log.error("onCancelActivitySignUpSuccessEvent:取消报名异常event:{}, e:{}",event, e);
                    throw new ServiceException("退款服务异常，联系客服");
                }
        }
    }



    @Async
    @EventListener
    public void onActivityCreateSuccessEvent4Push(ActivityCreateSuccessEvent event) {

        try {
            byte file[] = wxMaService.getQrcodeService()
                    .createQrcodeBytes("/pages/detail/detail?activityId=" + event.getActivity().getId(), 700);
            String picUrl = sysOssService.uploadFile2Oss(file, "activity-"+event.getActivity().getId() + ".png");
            // 更新一下
            activityService.update(new UpdateWrapper<Activity>().set("er_code_url", picUrl).eq("id", event.getActivity().getId()));
            log.info("二维码生成异常 picUrl：{} event:{}", picUrl,event);
        }catch (Exception e){
            log.error("二维码生成异常 e：{}", e);
        }

        if(event.getActivity().getMerchantId() != null) {
            Merchant merchant = merchantService.getById(event.getActivity().getMerchantId());
            if(merchant == null || MerchantStatusEnum.dowm.getValue() == merchant.getStatus()) {
                return;
            }
            // 通知商家创建人
            applicationEventPublisher.publishEvent(WxMpMessageEvent.builder()
                    .userId(merchant.getUserId())
                    .pushTemplateEnum(PushTemplateEnumNew.MERCHANT_USED_SUCCESS)
                     .miniAppPath("pages/detail/detail?activityId="+event.getActivity().getId())
                    .templateDataList(PushTemplateEnumNew.MERCHANT_USED_SUCCESS(
                            event.getActivity().getTitle(),
                            WzDateUtil.date2String(event.getActivity().getStartDate(),WzDateUtil.TIME_FORMAT_A),
                            event.getActivity().getContactName(),
                            // 活动名称 以及 组局人的联系方式
                            event.getActivity().getContactPhone()))
                    .build()
            );

            applicationEventPublisher.publishEvent(UserMessageEvent.builder()
                    .userId(merchant.getUserId())
                    .type(MessageTypeEnum.ACTIVITY_MESSAGE)
                    .withContent("场地预定通知", event.getActivity().getTitle())
                    .withActivityParam(event.getActivity().getId())
                    .build());

            // 通知官方人员
            applicationEventPublisher.publishEvent(WxMpAdminMessageEvent.builder()
                    .pushTemplateEnum(PushTemplateEnumNew.MERCHANT_USED_SUCCESS)
                    .miniAppPath("pages/detail/detail?activityId="+event.getActivity().getId())
                    .templateDataList(PushTemplateEnumNew.MERCHANT_USED_SUCCESS(
                            "[官方]"+event.getActivity().getTitle(),
                            WzDateUtil.date2String(event.getActivity().getStartDate(),WzDateUtil.TIME_FORMAT_A),
                            event.getActivity().getContactName(),
                            // 活动名称 以及 组局人的联系方式
                            event.getActivity().getContactPhone()))
                    .build()
            );
        }

    }

}
